import crypto from "crypto";
import request from "../utils/request.js";
import config from "../config.js";
import AwaitLock from "await-lock";

let token = '';
let lock = new AwaitLock();

export function clearToken() {
  console.log('Delete cached token')
  token = '';
}

export async function getToken() {
  if (token) {
    // console.log('Returning cached token:', token);
    return token;
  }
  // 如果 token 不存在，获取锁，防止多个并发请求重复获取 token
  await lock.acquireAsync();
  try {
    // 检查 token 是否已经被其它请求更新过
    if (token) {
      console.log('Returning cached token after waiting for lock:', token);
      return token;
    }
    console.log('Generating new token...');
    token = await login();
    console.log('Generated new token:', token);
    return token;
  } finally {
    lock.release(); // 释放锁
  }
}

export async function getPublicKey(userNo) {
  const { data } = await request({
    url: 'https://chadanwang.com/user/getPublicKey',
    method: 'post',
    headers: {
      "Content-Type": 'application/x-www-form-urlencoded'
    },
    data: {
      userNo,
    }
  });
  return data.data;
}

function encryptPassword(password, data) {
  const publicKey = `-----BEGIN PUBLIC KEY-----
${data.public_key}
-----END PUBLIC KEY-----`;
  const randomStr = data.random_str;
  const dataToEncrypt = password + randomStr;
  const buffer = Buffer.from(dataToEncrypt, 'utf-8');

  const encryptedBuffer = crypto.publicEncrypt(
    {
      key: publicKey,
      padding: crypto.constants.RSA_PKCS1_PADDING,  // 使用 PKCS#1 填充方案
    },
    buffer
  );
  return encodeURIComponent(encryptedBuffer.toString('base64'));
}

export async function login() {
  const { username, password } = config.account;
  const data = await getPublicKey(username);
  const encryptedPassword = encryptPassword(password, data);

  const res = await request({
    url: 'https://chadanwang.com/user/login',
    method: 'post',
    headers: {
      "Content-Type": 'application/x-www-form-urlencoded'
    },
    data: {
      userNo: username,
      loginPwd: encryptedPassword
    }
  });


  const body = res.data;
  token = body.data.remark;
  return token;
}

